package com.gaokao.demo.config;

import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONUtil;
import com.gaokao.demo.filter.JWTAuthenticationEntryPoint;
import com.gaokao.demo.filter.JWTAuthenticationFilter;
import com.gaokao.demo.filter.JWTAuthorizationFilter;
import com.gaokao.demo.service.CustomUserService;
import com.gaokao.demo.vo.ResultResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;


@Configuration
@EnableWebSecurity //开启spring security功能
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    SessionRegistry sessionRegistry;


    @Bean
    public SessionRegistry getSessionRegistry() {
        SessionRegistry sessionRegistry = new SessionRegistryImpl();
        return sessionRegistry;
    }

    //使用注解在配置类中直接实例化对象
    @Bean
    UserDetailsService customUserService(){
        return new CustomUserService();
    }




    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //解决Refused to display 'http://localhost:9000/cms/a/console' in a frame because it set 'X-Frame-Options' to 'deny'.
        http.headers().frameOptions().disable();
        http.csrf().disable(); //解决跨域的问题
        http.authorizeRequests()    //验证请求
            .and()
            .httpBasic()
            .and()
            .authorizeRequests()
                //放行option
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
            .anyRequest().authenticated() //必须授权才能范围
            .and()
            // 添加JWT登录拦截器
            .addFilter(new JWTAuthenticationFilter(authenticationManager()))
            // 添加JWT鉴权拦截器
            .addFilter(new JWTAuthorizationFilter(authenticationManager()))
            .sessionManagement()
            // 设置Session的创建策略为：Spring Security永不创建HttpSession 不使用HttpSession来获取SecurityContext
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .formLogin()
                .loginProcessingUrl("/login")
                .permitAll()
            .and()
            .exceptionHandling()
            // 匿名用户访问无权限资源时的异常
            .authenticationEntryPoint(new JWTAuthenticationEntryPoint());
        //开启跨域访问
        http.cors().disable();
        // 禁用缓存
        http.headers().cacheControl();

    }

    //AuthenticationManagerBuilder验证前台提交的数据
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        //BCryptPasswordEncoder指定密码的验证规则
        auth.userDetailsService(customUserService()).passwordEncoder(new BCryptPasswordEncoder());
    }
}
